import json, os
from uuid import uuid4
from django.db.models import F, Q
from ..tools.token import AuthJWT
from ..models.user import UserModel
from .base import BaseListView, BaseView
from django.http.request import HttpRequest
from kg_back.settings import SOURCE_DIR, SOURCE_URI
from ..models.user_serializer import UserInfoSerializer


# Create your views here.
class UserView(BaseView):
    ''' 用户操作视图 '''
    def get(self, request: HttpRequest):
        user = request.user
        return self.to_json(data=UserInfoSerializer(user).data)

    def put(self, request: HttpRequest):
        ''' 用户修改 '''
        allow_change_keys = ['nick_name', 'phone', 'gender', 'icon']
        data = json.loads(request.body)
        for key in data:
            if key in allow_change_keys:
                continue
            return self.resp_err(f'不允许修改的字段{key}')
        UserModel.objects.filter(id=request.user.id, is_delete=False).update(**data)
        return self.to_json(message='更新成功！')
    
    def delete(self, request: HttpRequest):
        ''' 用户注销 '''
        UserModel.objects.filter(id=request.user.id, is_delete=False).update(is_delete=True)
        return self.to_json(message='注销用户成功')


class UserLoginView(BaseView):
    ''' 用户登陆视图 '''
    def post(self, request: HttpRequest):
        ''' 用户注册 '''
        required_keys = ['username', 'password']
        if not len(request.POST):
            data = json.loads(request.body)
        else:
            data = request.POST
        username, password = map(data.get, required_keys)
        # 参数校验，必须字段是否填写
        if not all((username, password)):
            return self.resp_err(message='用户名(邮箱)、密码不能为空')
        # 用户查询和创建
        user = UserModel.objects.filter(
            Q(user_name=username) | Q(email=username), is_delete=False
        ).first()
        if not user:        # 如果用户不存在
            return self.resp_err(message='该用户不存在，请先注册!')
        if not user.check_password(password):
            return self.resp_err(message='密码错误!')
        token = AuthJWT.generate({'id': user.id, 'user_name': user.user_name})
        return self.to_json(message='登陆成功', data={'token': token})


class UserRegisterView(BaseView):
    ''' 用户注册视图 '''
    def post(self, request: HttpRequest):
        ''' 用户注册 '''
        required_keys = ['username', 'password', 'email']
        if not len(request.POST):
            data = json.loads(request.body)
        else:
            data = request.POST
        username, password, email = map(data.get, required_keys)
        print(username, password, email)
        # 参数校验，必须字段是否填写
        if not all((username, password, email)):
            return self.resp_err(message='用户名、密码或邮箱不能为空')
        # 用户查询和创建
        user = UserModel.objects.filter(user_name=username, is_delete=False).first()
        if not user:        # 如果用户不存在
            user = UserModel(user_name=username, password=password, email=email)
            user.save()
            return self.to_json(message='用户创建成功')
        return self.resp_err(message='该用户已经存在')


class UserLogoutView(BaseView):
    ''' 用户登出视图 '''
    def post(self, request: HttpRequest):
        ''' 响应登出状态码 50008 '''
        return self.to_json(code=50008, message='用户登出')


class UploadAvatar(BaseView):
    os.makedirs(SOURCE_DIR, exist_ok=True)
    def post(self, request: HttpRequest):
        ''' 上传图像 '''
        avatar = request.FILES.get('avatar')
        if not avatar:
            return self.resp_err('没有对应的图像')
        suffix = avatar.content_type.split('/')[-1]
        filename = f'{uuid4()}.{suffix}'
        save_path, url = os.path.join(SOURCE_DIR, filename), SOURCE_URI + '/' + filename
        with open(save_path, 'wb') as fp:
            for content in avatar.chunks():
                fp.write(content)
        return self.to_json(code=200, data={'url': url}, message='上传成功')


class UserListView(BaseListView):
    ''' 用户列表视图 '''
    def get(self, request: HttpRequest):
        serializer = UserInfoSerializer(UserModel.objects.filter(is_delete=False).all(), many=True)
        return self.to_json(data=serializer.data, message='获取用户列表成功')
    
    def delete(self, request: HttpRequest):
        if UserModel.objects.filter(id=request.GET.get('id')).update(is_delete=True):
            return self.to_json(message='删除成功！')
        return self.to_json(code=404, message='删除失败')
